package net.jjjshop.common.util.alimini;


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import lombok.extern.slf4j.Slf4j;
import net.jjjshop.common.entity.order.OrderCreditPay;
import net.jjjshop.common.util.OrderUtils;
import net.jjjshop.config.properties.SpringBootJjjProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static net.jjjshop.common.util.alimini.AliminiConfig.*;

/**
 * @description: 支付宝支付工具类
 * @author: dingli
 * @create: 2024-06-16 13:45
 **/
@Configuration
@Slf4j
public class AlipayUtils {
    @Autowired
    private SpringBootJjjProperties springBootJjjProperties;

    /**
     * 创建统一支付订单号
     * @return 订单号
     */
    /**
     * @param outTradeNo  商户订单号
     * @param totalAmount 支付金额
     * @param subject     商品标题
     * @return
     */
    public String tradeCreate(String openId, String outTradeNo, String orderNo, BigDecimal totalAmount, String paySource, String subject) throws AlipayApiException {

        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(AliminiConfig.getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
        AlipayTradeCreateModel model = new AlipayTradeCreateModel();

        // 设置商户订单号
        model.setOutTradeNo(outTradeNo);

        model.setBuyerOpenId(openId);

        // 设置产品码
        model.setProductCode("JSAPI_PAY");

        // 设置小程序支付中
        model.setOpAppId(APPID);

        model.setBody("订单号:" + orderNo);
        // 设置订单总金额
        model.setTotalAmount(totalAmount.toString());

        // 设置订单标题
        model.setSubject(subject);

        request.setBizModel(model);
        request.setNotifyUrl(springBootJjjProperties.getServerIp() + "/api/job/notify/aliPay");
        AlipayTradeCreateResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
            /**
             * 返回支付宝交易号,用于小程序吊起支付
             */
            return response.getTradeNo();
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return null;
    }

    /**
     * 创建统一支付订单号(芝麻先享)
     *
     * @param outTradeNo  商户订单号
     * @param totalAmount 支付金额
     * @param subject     商品标题
     * @return
     */
    public String tradeCreateZMXX(String openId, String outTradeNo, String orderNo, BigDecimal totalAmount, String paySource, String subject) throws AlipayApiException {
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(AliminiConfig.getAlipayConfig());
        AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
        request.setNotifyUrl(springBootJjjProperties.getServerIp() + "/api/job/notify/creditbizorderChangedNotify");//设置异步通知地址
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);//商家外部单号，商家自定义确保唯一
        bizContent.put("total_amount", totalAmount);
        bizContent.put("subject", subject + "芝麻先享,订单号:" + orderNo);
        bizContent.put("product_code", "JSAPI_PAY");//固定值
        bizContent.put("buyer_open_id", openId);//用户登入小程序授权获取到的id
        //设置扩展参数必填
        JSONObject extraParam = new JSONObject();
        extraParam.put("zmServiceId", ZMXX_SERVICE_ID);//芝麻业务人员配置发放
        extraParam.put("creditTradeScene", "CREDIT_PAY");//固定值
        bizContent.put("extend_params", extraParam);

        //商品明细信息，按需传入
        /*JSONArray goodsDetail = new JSONArray();
        JSONObject goods1 = new JSONObject();
        goods1.put("goods_id", "2023006******0900049579");
        goods1.put("goods_name", "花漾女士淡香水");
        goods1.put("quantity", 1);
        goods1.put("price", 0.01);
        goods1.put("goods_category", "商品类目");
        goodsDetail.add(goods1);
        bizContent.put("goods_detail", goodsDetail);
*/
        // 设置整体请求参数
        request.setBizContent(bizContent.toString());
        AlipayTradeCreateResponse response = alipayClient.execute(request);
        String tradeNo = response.getTradeNo();
        return tradeNo;
    }

    /**
     * 查询接口支付情况
     * 参考接口文档:https://opendocs.alipay.com/mini/03l4kc?scene=common&pathHash=ee5a7444
     *
     * @param out_trade_no
     * @throws AlipayApiException
     */
    public Boolean alipayTradeQuery(String out_trade_no, BigDecimal total_amount) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(AliminiConfig.getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();

        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(out_trade_no);


        request.setBizModel(model);

        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            //【描述】交易状态：WAIT_BUYER_PAY（交易创建，等待买家付款）、TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、TRADE_SUCCESS（交易支付成功）、TRADE_FINISHED（交易结束，不可退款）
            response.getTradeStatus();
            response.getTotalAmount();

            BigDecimal totalAmount = new BigDecimal(response.getTotalAmount());
            if (totalAmount.compareTo(total_amount) == 0) {
                return true;
            } else {
                log.error("金额不一致,{}{}", response.getTotalAmount(), response.getTradeNo());
            }


        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return false;
    }

    /**
     * 芝麻先享信用服务订单状态变更通知
     *
     * @param request
     */
    public JSONObject creditbizorderChanged(HttpServletRequest request) throws AlipayApiException {
        //获取支付宝POST过来反馈信息，将异步通知中收到的待验证所有参数都存放到map中
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //调用SDK验证签名
        //公钥验签示例代码
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGNTYPE);
        //公钥证书验签示例代码
        //   boolean flag = AlipaySignature.rsaCertCheckV1(params,alipayPublicCertPath,"UTF-8","RSA2");

        if (signVerified) {
            // TODO 验签成功后
            //按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success
            if (params.get("msg_method").equals("zhima.credit.payafteruse.creditbizorder.changed")) {
                //判断是芝麻先享通知
                JSONObject biz_contentJson = JSONObject.parseObject(params.get("biz_content"));
                biz_contentJson.get("credit_biz_order_id");//信用服务订单号
                biz_contentJson.get("out_order_no");//商户外部单号
                biz_contentJson.put("out_trade_no", biz_contentJson.get("out_order_no"));//商户外部单号
                biz_contentJson.get("trade_no");//支付宝交易号
                biz_contentJson.get("order_status");//信用服务订单状态.INIT: 下单状态；TRADE_CLOSED: 订单取消或者交易全额退款； TRADE_FINISHED：扣款成功状态。
                biz_contentJson.get("credit_pay_mode");//下单模式。用以区分订单类型，是普通下单还是信用下单。 信用下单模式取值：creditAdvanceV2
/*
                if (biz_contentJson.get("order_status").equals("INIT")) {
                    //信用下单成功


                } else if (biz_contentJson.get("order_status").equals("TRADE_CLOSED")) {
                    //订单取消或者交易全额退款
                } else if (biz_contentJson.get("order_status").equals("TRADE_FINISHED")) {
                    //扣款成功状态
                }else {
                    //异常
                }*/
                return biz_contentJson;

            }

        } else {
            // TODO 验签失败则记录异常日志，并在response中返回fail.
            return null;
        }
        return null;

        //ISV_GATEWAY_URL?charset=GBK&biz_content=
        //{
        //"credit_biz_order_id":"ZMCB01201712200000220000030977",
        //"out_order_no":"201904010000000060650000012345",
        //"trade_no":"20200119000000000000000",
        //"order_status":"INIT",
        //"biz_time":"2021-01-19 00:00:00",
        //"credit_pay_mode":"creditAdvanceV2",
        //"passback_params":"merchantBizType%3d3C%26merchantBizNo%3d201601001111"
        //}
        //&msg_method=zhima.credit.payafteruse.creditbizorder.changed&utc_timestamp=1516797622752&version=1.1&sign_type=RSA2&notify_id=d275fec564e62af6bedbcee73f3f05fi5x&app_id=2013121700999429&sign=I+Y/lvqYUEEc10EPdpntRhFIQ==
    }

    /**
     * 统一收单交易订单支付接口
     *
     * @param openId
     * @param totalAmount    订单总金额
     * @param trade_no       支付宝交易号
     * @param out_request_no 商家外部协议号，自定义确保唯一
     * @return
     * @throws AlipayApiException
     */
    public static String tradeOrderPay(String openId, BigDecimal totalAmount, String trade_no, String out_request_no) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayTradeOrderPayRequest request = new AlipayTradeOrderPayRequest();
        AlipayTradeOrderPayModel model = new AlipayTradeOrderPayModel();

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_request_no", out_request_no);//商家外部协议号，自定义确保唯一
        bizContent.put("trade_no", trade_no);//支付宝交易号
        bizContent.put("fulfillment_amount", totalAmount);//信用服务订单本次扣款金额，目前只支持全额扣款
        bizContent.put("order_pay_mode", "CREDIT_FULFILLMENT_ZM");//固定值
        model.setIsAsyncPay(false);//不允许异步通知扣款
        request.setBizModel(model);

        // 设置整体请求参数
        request.setBizContent(bizContent.toString());
        AlipayTradeOrderPayResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            response.getTradeNo();//支付宝交易号
            response.getOutTradeNo();//商户订单号
            response.getTotalAmount();//订单总金额
            response.getFulfillmentAmount();//实际履约金额，单位（元）。仅履约场景才会返回
            /**
             * 这里需要记录实际履约金额,新增履约表,记录履约时间
             */

            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return null;
    }

    /**
     * 先享后付退款
     *
     * @param totalAmount    订单总金额
     * @param outTradeNo       商户订单号
     * @param out_request_no 商家外部协议号，自定义确保唯一
     * @return
     * @throws AlipayApiException
     */
    public static Boolean tradeRefund(String outTradeNo, BigDecimal totalAmount, String out_request_no) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
//        bizContent.put("trade_no", trade_no);
        bizContent.put("refund_amount", totalAmount);//订单总金额
        bizContent.put("out_trade_no", outTradeNo);//商家订单唯一号
        bizContent.put("out_request_no", out_request_no);

        //扩展参数
        JSONObject extendParam = new JSONObject();
        extendParam.put("is_fulfilled", "true");//商家自行根据场景判断是否强制设置为已履约
        bizContent.put("extend_params", extendParam);

        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            /**
             * 处理订单状态
             */
            return true;
        } else {
            System.out.println("调用失败");
            return false;
        }
    }

    /**
     * 完结芝麻先享订单
     *
     * @param credit_biz_order_id
     * @param out_request_no
     * @return
     * @throws AlipayApiException
     */
    public static Boolean finishOrder(String credit_biz_order_id, String out_request_no) throws AlipayApiException {

        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        ZhimaCreditPayafteruseCreditbizorderFinishRequest request = new ZhimaCreditPayafteruseCreditbizorderFinishRequest();
        request.setBizContent("{" +
                "  \"out_request_no\":\"" + out_request_no + "\"," +
                "  \"credit_biz_order_id\":\"" + credit_biz_order_id + "\"," +
                "  \"is_fulfilled\":\"true\"," +
                "  \"remark\":\"完结订单\"" +
                "}");
        ZhimaCreditPayafteruseCreditbizorderFinishResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return true;
        } else {
            System.out.println("调用失败");
        }
        return false;
    }


    /**
     * alipay.fund.auth.order.app.freeze（线上资金授权冻结接口）
     *
     * @param out_order_no 商户订单号
     * @param totalAmount  金额
     * @param subject      标题
     * @return
     * @throws AlipayApiException
     */
    public static String createZmmydj(String out_order_no, BigDecimal totalAmount, String subject) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayFundAuthOrderAppFreezeRequest request = new AlipayFundAuthOrderAppFreezeRequest();
        AlipayFundAuthOrderAppFreezeModel model = new AlipayFundAuthOrderAppFreezeModel();

        // 设置订单标题
        model.setOrderTitle(subject);

        // 设置商户授权资金订单号
        model.setOutOrderNo(out_order_no);

        // 设置商户本次资金操作的请求流水号与outTradeNo一致
        model.setOutRequestNo(out_order_no);

        // 设置需要冻结的金额
        model.setAmount(totalAmount.toString());

        // 设置预授权订单相对超时时间,预授权订单允许的最晚授权时间，逾期将关闭该笔订单。取值范围：1m～15d。m-分钟，h-小时，d-天。 该参数数值不接受小数点， 如 1.5h，可转换为90m。
        model.setTimeoutExpress("2d");

        // 设置销售产品码
        model.setProductCode("PRE_AUTH_ONLINE");
        /**
         * 传入后用户仅能使用列表中的渠道进行支付，目前支持三种渠道，余额宝（MONEY_FUND）、花呗（PCREDIT_PAY）以及芝麻信用（CREDITZHIMA）。与禁用支付渠道不可同时传入
         * 【示例值】[{"payChannelType":"PCREDIT_PAY"},{"payChannelType":"MONEY_FUND"}]
         */

//        model.setEnablePayChannels("CREDITZHIMA");//
        /**
         * 厨房电器	RENT_KITCHENWARE
         * 手机	RENT_PHONE
         * 电脑/平板	RENT_COMPUTER
         * 珠宝/钻石/翡翠/黄金	RENT_GOLD
         * 二手数码	RENT_SECONDHAND_DIGITAL
         */
        // 设置业务扩展参数
//        model.setExtraParam("{\"category\": \"RENT_PHONE\",\"serviceId\": \"2024061300000000000108691200\"}");
        model.setExtraParam("{\"category\": \"RENT_PHONE\",\"serviceId\": \""+ ZMMY_SERVICE_ID + "\"}");

        // 设置免押受理台模式
        // 后付金额已知: POSTPAY
        //后付金额未知: POSTPAY_UNCERTAIN
        //纯免押: DEPOSIT_ONLY
        model.setDepositProductMode("DEPOSIT_ONLY");
        List<PostPayment> postPayments = new ArrayList<PostPayment>();

        List<PostPayment> postPayments_1 = new ArrayList<PostPayment>();
        PostPayment postPayments1 = new PostPayment();
        postPayments1.setName(subject);
        // 当免押模式为纯免押时：POSTPAY_UNCERTAIN ，setAmount为空
        postPayments1.setAmount(totalAmount.toString());
        postPayments1.setDescription("到期后系统自动扣款");
        postPayments.add(postPayments1);
        model.setPostPayments(postPayments_1);


        request.setBizModel(model);
        request.setNotifyUrl(notify_url);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayFundAuthOrderAppFreezeResponse response = alipayClient.sdkExecute(request);
         log.info("芝麻免押创建订单接口,{}",response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
            return response.getBody();

        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return null;
    }


    /**
     * 扣款接口:用户在商户侧已授权下单并享受服务后，商户使用授权单号通过本接口对用户已授权金额发起扣款。
     *
     * @param outTradeNo
     * @param totalAmount
     * @param subject
     * @return
     * @throws AlipayApiException
     */
    public static AlipayTradePayResponse tradePayMY(String outTradeNo, BigDecimal totalAmount, String subject, String authNo) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        AlipayTradePayModel model = new AlipayTradePayModel();
        // 设置商户订单号
        model.setOutTradeNo(outTradeNo);

        // 设置订单总金额
        model.setTotalAmount(totalAmount.toString());

        // 设置预授权确认模式 扣到用户钱时会同步关闭订单。 转交易完成后解冻剩余冻结金额: COMPLETE
        //转交易完成后不解冻剩余冻结金额: NOT_COMPLETE
        model.setAuthConfirmMode("NOT_COMPLETE");

        // 设置订单标题
        model.setSubject(subject + "押金");

        // 设置产品码
        model.setProductCode("PREAUTH_PAY");


        // 设置资金预授权单号
        model.setAuthNo(authNo);
        request.setNotifyUrl(notify_url);

        request.setBizModel(model);

/*        JSONObject bizContent = new JSONObject();
        bizContent.put("enable_pay_channels", "balance");
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("total_amount", totalAmount);
        bizContent.put("subject", "押金");
        bizContent.put("product_code", "PREAUTH_PAY");
        bizContent.put("auth_no", authNo);
        bizContent.put("auth_confirm_mode", "NOT_COMPLETE");
        request.setBizContent(bizContent.toJSONString());*/
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");
        AlipayTradePayResponse response = alipayClient.execute(request);

        log.info("扣款接口接口request:{}",alipayClient.toString());

        log.info("扣款接口接口,{}",response.getBody().toString());

        log.info(response.getBody());
        if (response.isSuccess()) {
            response.getTradeNo();
            response.getOutTradeNo();
            response.getReceiptAmount();//实收金额
            response.getTotalAmount();//交易金额
            response.getGmtPayment();//交易时间
            response.getFundBillList();//交易渠道
            log.info("调用成功");
            return response;

        } else {
            log.info("调用失败");
            return null;
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }


    /**
     * 资金授权撤销接口。
     *
     * @param out_order_no
     * @return
     * @throws AlipayApiException
     */
    public static Boolean cancelPayMY(String out_order_no) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        AlipayFundAuthOperationCancelRequest request = new AlipayFundAuthOperationCancelRequest();

        JSONObject bizContent = new JSONObject();

        // out_order_no与auth_no选择其一传入即可
        bizContent.put("out_order_no", out_order_no);
        //auth_no在授权冻结成功时返回参数中获得
        // bizContent.put("auth_no","2021081710002001640564315836");

        // out_request_no与operation_id选择其一传入即可
        //out_request_no与冻结流水号相同
        bizContent.put("out_request_no", out_order_no);
        // bizContent.put("operation_id","20161012405744018102");

        // 商家对本次撤销操作的附言描述，长度不超过100个字母或50个汉字
        bizContent.put("remark", "撤销授权");
        bizContent.put("notify_url", notify_url);

        // 设置整体请求参数
        request.setBizContent(bizContent.toString());

        // 使用execute方法发起请求
        AlipayFundAuthOperationCancelResponse response = alipayClient.execute(request);
        log.info("资金授权撤销接口,{}",response.getBody().toString());

        if (response.isSuccess()) {
            System.out.println("调用成功");
            return true;
        } else {
            System.out.println("调用失败");

        }
        return false;
    }

    /**
     * (统一收单交易退款接口)
     *
     * @param outTradeNo
     * @param refund_amount
     * @param out_request_no 同一次退款请求，如果调用接口失败或异常了，重试时需要保证退款请求号不能变更
     * @throws AlipayApiException
     */
    public static Boolean zmmyRefund(String outTradeNo, BigDecimal refund_amount, String out_request_no) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();

        // 设置商户订单号
        model.setOutTradeNo(outTradeNo);
        //退款请求号。 标识一次退款请求，需要保证在交易号下唯一，如需部分退款，则此参数必传。 注：针对同一次退款请求，如果调用接口失败或异常了，重试时需要保证退款请求号不能变更，防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。
        model.setOutRequestNo(out_request_no);

        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("refund_detail_item_list");
        model.setQueryOptions(queryOptions);
        model.setRefundAmount(refund_amount.toString());

        // 设置退款金额
        model.setRefundAmount(refund_amount.toString());

        // 设置退款原因说明
        model.setRefundReason("正常退款");


        request.setBizModel(model);
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        log.info("芝麻免押统一收单交易退款接口,{}",response.getBody().toString());

        if (response.isSuccess()) {
            System.out.println("调用成功");
            return true;

        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return false;
    }

    /**
     * 支付宝订单信息同步接口
     *
     * @param trade_no
     * @param out_request_no
     * @throws AlipayApiException
     */
    public static void zmmySync(String out_request_no, String trade_no) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradeOrderinfoSyncRequest request = new AlipayTradeOrderinfoSyncRequest();
        AlipayTradeOrderinfoSyncModel model = new AlipayTradeOrderinfoSyncModel();

        // 设置商户传入同步信息
        model.setOrderBizInfo("{\"status\":\"COMPLETE\"}");

        // 设置交易信息同步对应的业务类型
        //     * @param biz_type【描述】交易信息同步对应的业务类型，具体值与支付宝约定； 信用授权场景下传CREDIT_AUTH 信用代扣场景下传CREDIT_DEDUCT
        model.setBizType("CREDIT_DEDUCT");

        // 设置支付宝交易号
        model.setTradeNo(trade_no);

        // 设置外部请求号
        model.setOutRequestNo(out_request_no);

        request.setBizModel(model);
        AlipayTradeOrderinfoSyncResponse response = alipayClient.execute(request);
        log.info("支付宝订单信息同步接口,{}",response.getBody().toString());

        if (response.isSuccess()) {
            System.out.println("调用成功--已提示客户");


        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }


    /**
     * alipay.fund.auth.order.unfreeze(资金授权解冻接口)
     *
     * @param auth_no
     * @param out_request_no
     * @throws AlipayApiException
     */
    public static Boolean zmmyUnfreeze(String out_request_no, String auth_no,BigDecimal amount) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayFundAuthOrderUnfreezeRequest request = new AlipayFundAuthOrderUnfreezeRequest();

        JSONObject bizContent = new JSONObject();

        bizContent.put("auth_no", auth_no);//支付宝资金授权订单号。
        bizContent.put("out_request_no", out_request_no);//解冻请求流水号。
        bizContent.put("amount", amount.toString());//本次操作解冻的金额，单位为：元（人民币），精确到小数点后两位。
        bizContent.put("remark", "解冻资金:"+amount.toString());

        JSONObject extraParam = new JSONObject();
        JSONObject unfreezeBizInfo = new JSONObject();
        unfreezeBizInfo.put("bizComplete", true);
        extraParam.put("unfreezeBizInfo", unfreezeBizInfo);
        bizContent.put("extra_param", extraParam);

        // 设置整体请求参数
        request.setBizContent(bizContent.toString());

        // 使用execute方法发起请求
        AlipayFundAuthOrderUnfreezeResponse response = alipayClient.execute(request);
        log.info("资金授权解冻接口,{}",response.getBody().toString());
        if (response.isSuccess()) {
            System.out.println("调用成功");

            return true;
        } else {
            System.out.println("调用失败");
        }
        return false;
    }

    /**
     * alipay.trade.close(统一收单交易关闭接口)
     *
     * @param trade_no
     * @throws AlipayApiException
     */
    public static Boolean zmmyClose(String trade_no) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("trade_no", trade_no);
        request.setBizContent(bizContent.toString());
        AlipayTradeCloseResponse response = alipayClient.execute(request);

        log.info("资金授权解冻接口,{}",response.getBody().toString());
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return true;
        } else {
            System.out.println("调用失败");
        }
        return false;
    }


    public static void main(String[] args) throws AlipayApiException {
//        cancelPayMY("20240707000100282140");
        finishOrder("2024071210002001250591207099", OrderUtils.geneOrderNo(10003));
//        zmmySync("2024071110002001250590476649","20240711000100287291");

        //扣款
//        OrderCreditPay koukuan = koukuan();
//        tradePayMY(koukuan().getOutTradeNo(), koukuan.getPayPrice(), "扣款", "2024071710002001250594571031");

//        zmmyUnfreeze(OrderUtils.geneOrderNo(10028), "2024071710002001250594496513", new BigDecimal("0.01"));
//        zmmyUnfreeze(OrderUtils.geneOrderNo(10003), "20240713000100283549", new BigDecimal("0.02"));
//        finishOrder("ZMCB99202407140000250067577245",OrderUtils.geneOrderNo(10003) );
//        finishOrder("ZMCB99202407100000250067097020",OrderUtils.geneOrderNo(10003) );
//        zmmyClose("20240623000100045150");

//        zmmyRefund("20240718000100283332", new BigDecimal("0.01"), OrderUtils.geneOrderNo(10028));
    }

   static OrderCreditPay koukuan() {
    OrderCreditPay    orderCreditPay = new OrderCreditPay();
        orderCreditPay.setOrderId(177);
        orderCreditPay.setOutRequestNo(OrderUtils.geneOrderNo(10028));
        orderCreditPay.setPayStatus(10);
        orderCreditPay.setPayPrice(new BigDecimal("0.01"));
        orderCreditPay.setPayType(50);//免押扣款
        orderCreditPay.setOutTradeNo(OrderUtils.geneOrderNo(10028));
        orderCreditPay.setRemark("remark" + "手动扣款");

       return orderCreditPay;
    }

}
